/*
* Cedarx framework.
* Copyright (c) 2008-2015 Allwinner Technology Co. Ltd.
*
* This file is part of Cedarx.
*
* Cedarx is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*/

#include "mjpeg_dec_lib.h"
#include "veregister.h"

#define SYS_WriteByte(uAddr, bVal) 		{*(volatile uint8_t *)(uAddr) = (bVal);}
#define SYS_WriteWord(uAddr, wVal) 		{*(volatile uint16_t *)(uAddr) = (wVal);}
#define SYS_WriteDWord(uAddr, dwVal) 	{*(volatile uint32_t *)(uAddr) = (dwVal);}
#define SYS_ReadByte(uAddr) 			bVal = (*(volatile uint8_t *)(uAddr));
#define SYS_ReadWord(uAddr) 			wVal = (*(volatile uint16_t *)(uAddr));
#define SYS_ReadDWord(uAddr) 			(*(volatile uint32_t *)(uAddr));

#define MPEG_REGS_BASE              ((uint32_t)ve_get_reglist(REG_GROUP_MPEG_DECODER))

/* offset */
#define MPEG_REG_o_VE_TRIGR         0x18
#define MPEG_REG_o_VLD_START        0x28
#define MPEG_REG_o_VLD_OFFSET       0x2C
#define MPEG_REG_o_VLD_LEN          0x30
#define MPEG_REG_o_VLD_END          0x34
#define MPEG_REG_o_QMINPUT          0x80
#define MPEG_REG_o_JPG_MCU0         0xB8
#define MPEG_REG_o_JPG_MCU1         0xBC
#define MPEG_REG_o_JPG_RESINT       0xC0
#define MPEG_REG_o_JPG_YADDR        0xCC
#define MPEG_REG_o_JPG_CADDR        0xD0
#define MPEG_REG_o_ROTAT_CTL        0xD4
#define MPEG_REG_o_SRAM_RW_OFFSET   0xE0
#define MPEG_REG_o_SRAM_RW_DATA     0xE4

/* registers */
#define MPEG_REG_VE_TRIGR           ( MPEG_REGS_BASE + MPEG_REG_o_VE_TRIGR       )
#define MPEG_REG_VLD_START          ( MPEG_REGS_BASE + MPEG_REG_o_VLD_START      )
#define MPEG_REG_VLD_OFFSET         ( MPEG_REGS_BASE + MPEG_REG_o_VLD_OFFSET     )
#define MPEG_REG_VLD_LEN            ( MPEG_REGS_BASE + MPEG_REG_o_VLD_LEN        )
#define MPEG_REG_VLD_END            ( MPEG_REGS_BASE + MPEG_REG_o_VLD_END        )
#define MPEG_REG_QMINPUT            ( MPEG_REGS_BASE + MPEG_REG_o_QMINPUT        )
#define MPEG_REG_JPG_MCU0           ( MPEG_REGS_BASE + MPEG_REG_o_JPG_MCU0       )
#define MPEG_REG_JPG_MCU1           ( MPEG_REGS_BASE + MPEG_REG_o_JPG_MCU1       )
#define MPEG_REG_JPG_RESINT         ( MPEG_REGS_BASE + MPEG_REG_o_JPG_RESINT     )
#define MPEG_REG_JPG_YADDR          ( MPEG_REGS_BASE + MPEG_REG_o_JPG_YADDR      )
#define MPEG_REG_JPG_CADDR          ( MPEG_REGS_BASE + MPEG_REG_o_JPG_CADDR      )
#define MPEG_REG_ROTAT_CTL          ( MPEG_REGS_BASE + MPEG_REG_o_ROTAT_CTL      )
#define MPEG_REG_SRAM_RW_OFFSET     ( MPEG_REGS_BASE + MPEG_REG_o_SRAM_RW_OFFSET )
#define MPEG_REG_SRAM_RW_DATA       ( MPEG_REGS_BASE + MPEG_REG_o_SRAM_RW_DATA   )

static uint16_t DhtDefault[] = {
	0x0000,0x0000,0x0002,0x000e,0x001e,0x003e,0x007e,0x00fe,
	0x01fe,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
	0x0000,0x0601,0x0807,0x0a09,0x0c0b,0x0c0c,0x0c0c,0x0c0c,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0004,0x000a,0x001a,0x003a,0x0078,0x00f8,
	0x01f6,0x03f6,0x07f6,0x0ff4,0x1ff0,0x3fe0,0x7fc0,0xff82,
	0x0000,0x0302,0x0906,0x0f0b,0x1712,0x201c,0x2424,0x2524,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0006,0x000e,0x001e,0x003e,0x007e,0x00fe,
	0x01fe,0x03fe,0x07fe,0xffff,0xffff,0xffff,0xffff,0xffff,
	0x0000,0x0403,0x0605,0x0807,0x0a09,0x0c0b,0x0c0c,0x0c0c,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0004,0x000a,0x0018,0x0038,0x0078,0x00f6,
	0x01f4,0x03f6,0x07f6,0x0ff4,0x1ff0,0x3fe0,0x7fc2,0xff88,
	0x0000,0x0302,0x0905,0x100d,0x1b14,0x2420,0x2828,0x2b29,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0100,0x0302,0x0504,0x0706,0x0908,0x0b0a,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0201,0x0003,0x1104,0x1205,0x3121,0x0641,0x5113,0x0761,
	0x7122,0x3214,0x9181,0x08a1,0x4223,0xc1b1,0x5215,0xf0d1,
	0x3324,0x7262,0x0982,0x160a,0x1817,0x1a19,0x2625,0x2827,
	0x2a29,0x3534,0x3736,0x3938,0x433a,0x4544,0x4746,0x4948,
	0x534a,0x5554,0x5756,0x5958,0x635a,0x6564,0x6766,0x6968,
	0x736a,0x7574,0x7776,0x7978,0x837a,0x8584,0x8786,0x8988,
	0x928a,0x9493,0x9695,0x9897,0x9a99,0xa3a2,0xa5a4,0xa7a6,
	0xa9a8,0xb2aa,0xb4b3,0xb6b5,0xb8b7,0xbab9,0xc3c2,0xc5c4,
	0xc7c6,0xc9c8,0xd2ca,0xd4d3,0xd6d5,0xd8d7,0xdad9,0xe2e1,
	0xe4e3,0xe6e5,0xe8e7,0xeae9,0xf2f1,0xf4f3,0xf6f5,0xf8f7,
	0xfaf9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0100,0x0302,0x0504,0x0706,0x0908,0x0b0a,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0100,0x0302,0x0411,0x2105,0x0631,0x4112,0x0751,0x7161,
	0x2213,0x8132,0x1408,0x9142,0xb1a1,0x09c1,0x3323,0xf052,
	0x6215,0xd172,0x160a,0x3424,0x25e1,0x17f1,0x1918,0x261a,
	0x2827,0x2a29,0x3635,0x3837,0x3a39,0x4443,0x4645,0x4847,
	0x4a49,0x5453,0x5655,0x5857,0x5a59,0x6463,0x6665,0x6867,
	0x6a69,0x7473,0x7675,0x7877,0x7a79,0x8382,0x8584,0x8786,
	0x8988,0x928a,0x9493,0x9695,0x9897,0x9a99,0xa3a2,0xa5a4,
	0xa7a6,0xa9a8,0xb2aa,0xb4b3,0xb6b5,0xb8b7,0xbab9,0xc3c2,
	0xc5c4,0xc7c6,0xc9c8,0xd2ca,0xd4d3,0xd6d5,0xd8d7,0xdad9,
	0xe3e2,0xe5e4,0xe7e6,0xe9e8,0xf2ea,0xf4f3,0xf6f5,0xf8f7,
	0xfaf9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
};

static void set_internal_intr_enable_bits(void)
{
    volatile uint32_t* ve_top_reg;
    volatile uint32_t* ve_intr_ctrl_reg;
    uint32_t 		  mode;

    ve_top_reg = (uint32_t*)ve_get_reglist(REG_GROUP_VETOP);

    mode = (*ve_top_reg) & 0xf;
    
	/* estimate Which video format */
    switch (mode)
    {
        case 0:
            ve_intr_ctrl_reg = (uint32_t *)((uint32_t)ve_get_reglist(REG_GROUP_MPEG_DECODER) + 0x14);
        	*ve_intr_ctrl_reg |= 0x7c;
            break;
            
        default:
            break;
    }
    
    return;
}

static void JpegClearStatusReg(void)
{
    volatile uint32_t* ve_top_reg;
    volatile uint32_t* ve_status_reg;
    uint32_t 		  mode;

    ve_top_reg = (uint32_t*)ve_get_reglist(REG_GROUP_VETOP);

    mode = (*ve_top_reg) & 0xf;
    
	/* estimate Which video format */
    switch (mode)
    {
        case 0:
            ve_status_reg = (uint32_t *)((uint32_t)ve_get_reglist(REG_GROUP_MPEG_DECODER) + 0x1c);
        	*ve_status_reg |= 0xf;
            break;
        default:
            break;
    }
    
    return;
}

int32_t SetJpegFormat(JpegDec* jpgctx)
{
	int32_t fmt;

	fmt = jpgctx->curCompInfo[0].hSampFactor << 20 |
		  jpgctx->curCompInfo[0].vSampFactor << 16 |
		  jpgctx->curCompInfo[1].hSampFactor << 12 |
		  jpgctx->curCompInfo[1].vSampFactor <<  8 |
		  jpgctx->curCompInfo[2].hSampFactor <<  4 |
		  jpgctx->curCompInfo[2].vSampFactor;

	jpgctx->maxHSampFactor = MAX(MAX(jpgctx->curCompInfo[0].hSampFactor,
										jpgctx->curCompInfo[1].hSampFactor),
										jpgctx->curCompInfo[2].hSampFactor);

	jpgctx->maxVSampFactor = MAX(MAX(jpgctx->curCompInfo[0].vSampFactor,
										jpgctx->curCompInfo[1].vSampFactor),
										jpgctx->curCompInfo[2].vSampFactor);

	if(fmt == 0x211111)
		jpgctx->jpegFormat = JPEG422;
	else if(fmt == 0x221111)
		jpgctx->jpegFormat = JPEG420;
	else if(fmt == 0x121111)
		jpgctx->jpegFormat = JPEG422T;
	else if(fmt == 0x411111)
		jpgctx->jpegFormat = JPEG411;
	else if(fmt == 0x111111)
		jpgctx->jpegFormat = JPEG444;
	else if(fmt == 0x110000)
		jpgctx->jpegFormat = JPEG400;
	else
	{
		jpgctx->jpegFormat = JPEGERR;
		return 0;
	}

	return 1;
}

int32_t FillJpegHuffmanTable(JpegDec* jpgctx)
{
	int32_t 					i;
	JHuffTable*				pJpegHuff;
	JpegComponentInfo*	compptr = 0;
	uint16_t 					Huffman_Table_Sram[1024];

	if(!jpgctx->hasDht)
	{
		if(!jpgctx->hasConfigDht)
		{	//copy default dht to sramf
			int32_t* ptr = (int32_t*)DhtDefault;

			SYS_WriteDWord(MPEG_REG_SRAM_RW_OFFSET, 0);

			for(i=0;i<512;i++)
			{
				SYS_WriteDWord(MPEG_REG_SRAM_RW_DATA, *ptr++);
			}
		}

		return 0;//maybe goes here
	}

	for (i = 0; i < jpgctx->nNumComponents; i++)
	{
		compptr = &jpgctx->curCompInfo[i];
		if (compptr->componentId == jpgctx->seqCompId[0])
			break;
	}

	//Y DC
	pJpegHuff = &jpgctx->dcHuffTbl[compptr->dcTblNo];//&mJpegHuffTable[0][dc_index[0]];
	for(i=0;i<16;i++)
		Huffman_Table_Sram[i] = pJpegHuff->startCode[i];
	for(i=0;i<16;i+=2)
		Huffman_Table_Sram[16+(i>>1)] = (pJpegHuff->offset[i+1]<<8) | pJpegHuff->offset[i];
	for(i=0;i<8;i++)
		Huffman_Table_Sram[24+i] = 0;
	for(i=0;i<256;i+=2)
		Huffman_Table_Sram[512+(i>>1)] = (pJpegHuff->symbol[i+1]<<8) | pJpegHuff->symbol[i];

	//Y AC
	pJpegHuff = &jpgctx->acHuffTbl[compptr->acTblNo];
	for(i=0;i<16;i++)
		Huffman_Table_Sram[32+i] = pJpegHuff->startCode[i];
	for(i=0;i<16;i+=2)
		Huffman_Table_Sram[32+16+(i>>1)] = (pJpegHuff->offset[i+1]<<8) | pJpegHuff->offset[i];
	for(i=0;i<8;i++)
		Huffman_Table_Sram[32+24+i] = 0;
	for(i=0;i<256;i+=2)
		Huffman_Table_Sram[640+(i>>1)] = (pJpegHuff->symbol[i+1]<<8) | pJpegHuff->symbol[i];

	for (i = 0; i < jpgctx->nNumComponents; i++)
	{
		compptr = &jpgctx->curCompInfo[i];
		if (compptr->componentId == jpgctx->seqCompId[1])
			break;
	}

	//C DC
	pJpegHuff = &jpgctx->dcHuffTbl[compptr->dcTblNo];
	for(i=0;i<16;i++)
		Huffman_Table_Sram[64+i] = pJpegHuff->startCode[i];
	for(i=0;i<16;i+=2)
		Huffman_Table_Sram[64+16+(i>>1)] = (pJpegHuff->offset[i+1]<<8) | pJpegHuff->offset[i];
	for(i=0;i<8;i++)
		Huffman_Table_Sram[64+24+i] = 0;
	for(i=0;i<256;i+=2)
		Huffman_Table_Sram[768+(i>>1)] = (pJpegHuff->symbol[i+1]<<8) | pJpegHuff->symbol[i];

	//C AC
	pJpegHuff = &jpgctx->acHuffTbl[compptr->acTblNo];
	for(i=0;i<16;i++)
		Huffman_Table_Sram[96+i] = pJpegHuff->startCode[i];
	for(i=0;i<16;i+=2)
		Huffman_Table_Sram[96+16+(i>>1)] = (pJpegHuff->offset[i+1]<<8) | pJpegHuff->offset[i];
	for(i=0;i<8;i++)
		Huffman_Table_Sram[96+24+i] = 0;
	for(i=0;i<256;i+=2)
		Huffman_Table_Sram[896+(i>>1)] = (pJpegHuff->symbol[i+1]<<8) | pJpegHuff->symbol[i];

	for(i=128;i<512;i++)
		Huffman_Table_Sram[i] = 0;

	{
		int32_t* ptr = (int32_t*)Huffman_Table_Sram;

		SYS_WriteDWord(MPEG_REG_SRAM_RW_OFFSET, 0);

		for(i=0;i<512;i++)
		{
			SYS_WriteDWord(MPEG_REG_SRAM_RW_DATA, *ptr++);
		}
	}

	return 0;
}



int32_t InitJpegHw(JpegDec* jpgctx)
{
	int32_t i;
	int32_t input_data;
	int32_t YQuantTbl;
	int32_t CQuantTbl;

	SYS_WriteDWord(MPEG_REG_JPG_RESINT, 0 | jpgctx->nRestartInterval)
	//set picture level video engine
	SYS_WriteByte(MPEG_REG_VE_TRIGR+3, (jpgctx->jpegFormat<<3)|3)

	YQuantTbl = jpgctx->curCompInfo[0].quantTblNo;
	CQuantTbl = jpgctx->curCompInfo[1].quantTblNo;

	for(i=0;i<64;i++)
	{
		input_data = (i<<8) | (1<<14);
		input_data |= jpgctx->QTab[YQuantTbl][i];
		SYS_WriteDWord(MPEG_REG_QMINPUT,input_data);
	}

	for(i=0;i<64;i++)
	{
		input_data = (i<<8);
		input_data |= jpgctx->QTab[CQuantTbl][i];
		SYS_WriteDWord(MPEG_REG_QMINPUT,input_data);
	}

	SYS_WriteDWord(MPEG_REG_JPG_YADDR, jpgctx->nRefPicLumaAddr);
	SYS_WriteDWord(MPEG_REG_JPG_CADDR, jpgctx->nRefPicChromaAddr);

	{
		int32_t mcuHsize,mcuVsize;

		mcuHsize = jpgctx->maxHSampFactor<<3;
		mcuVsize = jpgctx->maxVSampFactor<<3;
		jpgctx->mcuWidth  = (uint16_t)((jpgctx->nWidth  + mcuHsize - 1) / mcuHsize); //round up
		jpgctx->mcuHeight = (uint16_t)((jpgctx->nHeight + mcuVsize - 1) / mcuVsize); //round up
	}
	input_data = (jpgctx->mcuHeight-1)<<16 | (jpgctx->mcuWidth-1);
	SYS_WriteDWord(MPEG_REG_JPG_MCU0, input_data);
	input_data = 0;
	input_data <<= 8;
	SYS_WriteDWord(MPEG_REG_ROTAT_CTL, input_data);

	FillJpegHuffmanTable(jpgctx);
	SYS_WriteDWord(MPEG_REG_VLD_END, (uint32_t)AdapterMemGetPhysicAddress((void*)(jpgctx->pVbvBase+jpgctx->nVbvSize-1)));

	return 1;
}



int32_t JpegHwDec(JpegDec* jpgctx)
{
	int32_t ret;
	uint32_t tmp;
	int32_t input_data;

	set_internal_intr_enable_bits();
	
	SYS_WriteDWord(MPEG_REG_VLD_OFFSET, (jpgctx->data - jpgctx->pVbvBase)<<3);
	SYS_WriteDWord(MPEG_REG_VLD_LEN, jpgctx->nFrameSize<<3);

	tmp = (uint32_t)AdapterMemGetPhysicAddress((void*)jpgctx->pVbvBase);
	tmp = (tmp>>28) | (tmp&0x0ffffff0);
	SYS_WriteDWord(MPEG_REG_VLD_START,  7<<28 | tmp);

	SYS_WriteByte(MPEG_REG_VE_TRIGR, 0x0e);

	ret = 0;
    AdapterVeWaitInterrupt();
	
	JpegClearStatusReg();

	if(ret == -1)
		return 0;

	return 1;
}



